/**
 * Project Reactor
 */


#include "../include/SocketIO.h"
#include "../include/TLVmsg.h"
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
#include <iostream>

using std::vector;
using std::cerr;
using std::endl;
using std::cout;


/**
 * SocketIO implementation
 */
SocketIO::SocketIO(int fd)
:_fd(fd)
{

}

/**
 * @param buff
 * @param len
 * @return int
 */
int SocketIO::readn(char * buff, int len) {
    cout << "SocketIO readn() 35" << endl;
int left = len;
	char * p = buff;
    //提问：left的值有可能小于0吗？不可能小于0，退出循环时，left等于0
	while(left > 0) {
    cout << "SocketIO readn() 40" << endl;

		int ret = ::recv(_fd, p, left, 0);
    cout << "SocketIO readn() 43 recvnum = " << ret << endl;

		if(ret == -1 && errno == EINTR)
			continue;
		else if(ret == -1) {
			perror("read");
			return len - left;
		}
		else if(ret == 0) {//连接断开
			return len - left;
		} else {
			left -= ret;
			p += ret;
		}
	}
	return len - left;    
}
void SocketIO::readMsg(int * taskType, string &msg)
{

    cout << "SocketIO.cpp readMsg() 58 " << endl;
    char header[6];
    if(readn(header, 6) != 6)
    {
        cerr << "fali read header" << endl;
    }
    uint16_t tag = 0;
    uint32_t len = 0;
     // 假设大端字节序(Big Endian)
    tag = (header[0] << 8) | header[1];
    *taskType = static_cast<int>(tag);
    len = (header[2] << 24) | (header[3] << 16) | (header[4] << 8) | header[5];
    // 使用vector代替VLA
    std::vector<char> buffer(len);

    // 读取消息体
    if (readn(buffer.data(), len) != static_cast<int>(len)) {
        cerr << "read msg failed" << endl;
    }

    // 正确处理字符串，使用带长度的构造函数
    msg.assign(buffer.data(), len);
    cout << "SocketIO.cpp readMsg() 78  msg = " << msg << " tasktype = "
        << *taskType << endl;
    
}

/**
 * @param buff
 * @param len
 * @return int  
 */
int SocketIO::readline(char * buff, int maxlen) {
    int left = maxlen - 1;
	char * p = buff;
	int ret;
	int total = 0;
	while(left > 0) {
		ret = recvPeek(p, left);
		//查找 '\n'
		for(int idx = 0; idx != ret; ++idx) {
			if(p[idx] == '\n') {
				int sz = idx + 1;
				readn(p, sz);//从内核缓冲区中移走
				total += sz;
				p += sz;
				*p = '\0';
				return total;
			}
		}
		//如果没有发现 '\n'
		readn(p, ret);
		left -= ret;
		p += ret;
		total += ret;
	}
	*p = '\0';// 最终没有发现'\n'
	return total;
}

/**
 * @param buff
 * @param len
 * @return int
 */
int SocketIO::recvPeek(char* buff, int len) {
    int ret;
	do {
		ret = ::recv(_fd, buff, len, MSG_PEEK);
	} while(ret == -1 && errno == EINTR);
	return ret;
}

int SocketIO::recvPeek() {
    int ret;
    char buf[20] = {0};
	do {
		ret = ::recv(_fd, buf, sizeof(buf), MSG_PEEK);
	} while(ret == -1 && errno == EINTR);
	return ret;
}


int SocketIO::sendn(const char * buff, int len)
{
    int left = len;
	const char * p = buff;
	while(left > 0) {
		int ret = ::send(_fd, p, left, 0);
		if(ret == -1 && errno == EINTR)
			continue;
		else if(ret == -1) {
			perror("write");
			return len - left;
		} else {
			left -= ret;
			p += ret;
		}
	}
	return len - left;

}
